#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>

struct msg_t {
    struct msg_t *next;
    int num;
};

struct msg_t *head;
pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

void *consumer(void *p)
{
    struct msg_t *msg;

    for (;;) {
        pthread_mutex_lock(&lock);
        while (NULL == head)
            pthread_cond_wait(&has_product, &lock);
        msg = head;
        head = msg->next;
        pthread_mutex_unlock(&lock);

        printf("consume:%d\n", msg->num);
        free(msg);
        sleep(rand() % 5);
    }
    return NULL;
}

void *producer(void *p)
{
    struct msg_t *msg;
    for (;;) {
        msg = malloc(sizeof(struct msg_t));
        msg->num = rand() % 1000 + 1;
        printf("produce:%d\n", msg->num);
        
        pthread_mutex_lock(&lock);
        msg->next = head;
        head = msg;
        pthread_mutex_unlock(&lock);

        pthread_cond_signal(&has_product);
        sleep(rand() % 5);
    }
    return NULL;
}

int main(int argc, char **argv)
{
    pthread_t pid, cid;

    srand(time(NULL));
    pthread_create(&pid, NULL, producer, NULL);
    pthread_create(&cid, NULL, consumer, NULL);
    pthread_join(pid, NULL);
    pthread_join(cid, NULL);
    return 0;
}

